import type { AxiosPromise } from "axios";
import type { EnumEntryReq, Entry, LayEntry } from "./types";
import request from "../utils/request";

//枚举字典类.
export class EnumDict {
  //模块名
  module: string;
  //枚举类名
  enumClass: string;
  //枚举类型
  type: number;
  //枚举值
  values: Entry[] = reactive([]);
  //是否初始化
  init: boolean = false;

  constructor(module: string, enumClass: string, type: number = 0) {
    this.module = module;
    this.enumClass = enumClass;
    this.type = type;
    //获取枚举值.
    this.useEnumValues();
  }

  useEnumValues(): Promise<Entry[]> {
    return new Promise<Entry[]>((resolve, reject) => {
      enumMapCache(this.module, this.enumClass, this.type).then((data: Entry[]) => {
        this.values.length = 0;
        this.values.push(...data);
        this.init = true;
        resolve(this.values);
      });
    });
  }

  getEnumValue(key: string): string {
    for (const obj of this.values) {
      if (obj.key == key) {
        return obj.value;
      }
    }
    return "";
  }
}

/**
 * 查询枚举键值对
 * @param className 枚举全名.
 * @param type 枚举分类,默认0, -1 查询全部枚举.
 * @returns 枚举键值对.
 */
function enumMap(module: string, className: string, type?: number): AxiosPromise<Entry[]> {
  const query: EnumEntryReq = { className, type };
  return request({
    url: "/v1/" + module + "/enum/entry",
    method: "get",
    params: query
  });
}

/** 查询缓存枚举键值对 */
export async function enumMapCache(
  module: string,
  className: string,
  type?: number
): Promise<Entry[]> {
  return new Promise<Entry[]>((resolve, reject) => {
    const enumKey: string = `enum_${className}${type ? "_" + type : ""}`;
    let enumStr = sessionStorage.getItem(enumKey);
    if (enumStr) {
      resolve(JSON.parse(enumStr));
    }
    if (!enumStr) {
      enumMap(module, className, type).then(({ data }) => {
        enumStr = JSON.stringify(data.values);
        if (data && data.values != undefined) {
          sessionStorage.setItem(enumKey, enumStr);
        }
        resolve(JSON.parse(enumStr));
      });
    } else {
      reject("NOT FUND!");
    }
  });
}

// 定义 BizDict 接口
export abstract class BizDict<T extends Entry = Entry> {
  // 业务数据，应该是一个可响应的 Entry 数组引用
  values: T[] = reactive([]);
  // 查询条件
  query: any;

  constructor(query: any) {
    this.query = query;
  }

  // 获取业务数据的方法，根据查询条件返回一个 Entry 数组的引用
  abstract useValues(): Promise<T[]>;

  // 根据给定键获取业务数据项的值的方法
  getValue(key: string): string {
    for (const obj of this.values) {
      if (obj.key == key) {
        return obj.value;
      }
    }
    return "";
  }
}

//启用/禁用
export class EnableBizDict extends BizDict {
  constructor(query: any) {
    super(query);
    this.useValues();
  }
  useValues(): Promise<Entry[]> {
    return new Promise((resolve, reject) => {
      this.values.length = 0;
      this.values.push({ key: "true", value: "启用" });
      this.values.push({ key: "false", value: "禁用" });
      resolve(this.values);
    });
  }
}

// 自定义
export class CustomBizDict {
  values = reactive([] as Entry[]);
  // 查询条件
  query: any;

  constructor(results: any, query: any) {
    this.values.length = 0;
    this.values.push(...results.value);
    this.query = query;
  }
  // 根据给定键获取业务数据项的值的方法
  getValue(key: string | boolean): string {
    for (const obj of this.values) {
      if (obj.key == key) {
        return obj.value;
      }
    }
    return "";
  }
}

// 定义 BizLayDict 接口
export abstract class BizLayDict {
  // 业务数据，应该是一个可响应的 Entry 数组引用
  values: LayEntry[] = reactive([] as LayEntry[]);
  // 查询条件
  query: any;

  constructor(query: any) {
    this.query = query;
  }

  // 获取业务数据的方法，根据查询条件返回一个 Entry 数组的引用
  abstract useValues(): Promise<LayEntry[]>;

  // 实现 getValue 方法
  getValue(key: string): string {
    const value = this.findLayEntryByValue(this.values, key);
    if (value) {
      return value.label;
    }
    return "";
  }

  findLayEntryByValue(entries: LayEntry[], targetValue: string): LayEntry | undefined {
    for (const entry of entries) {
      if (entry.value === targetValue) {
        return entry;
      }
      if (entry.children && entry.children.length > 0) {
        const foundInChildren = this.findLayEntryByValue(entry.children, targetValue);
        if (foundInChildren) {
          return foundInChildren;
        }
      }
    }
    return undefined; // 如果没有找到匹配项，则返回undefined
  }
}
